home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995 February: Tool Chest / Dev.CD Feb 95 / Dev.CD Feb 95.toast / Tool Chest / Development Tools & Languages / Dylan Related / Mindy-1.1 (sources only) / mindy-1.1 / libraries / dylan / array.dylan next >
Encoding:
Text File  |  1994-06-28  |  7.7 KB  |  280 lines  |  [TEXT/ttxt]

  1. module:   dylan
  2. language: infix-dylan
  3. author:   Nick Kramer (nkramer@cs.cmu.edu)
  4. rcs-header: $Header: array.dylan,v 1.3 94/06/27 17:10:15 wlott Exp $
  5.  
  6. //======================================================================
  7. //
  8. // Copyright (c) 1994  Carnegie Mellon University
  9. // All rights reserved.
  10. // 
  11. // Use and copying of this software and preparation of derivative
  12. // works based on this software are permitted, including commercial
  13. // use, provided that the following conditions are observed:
  14. // 
  15. // 1. This copyright notice must be retained in full on any copies
  16. //    and on appropriate parts of any derivative works.
  17. // 2. Documentation (paper or online) accompanying any system that
  18. //    incorporates this software, or any part of it, must acknowledge
  19. //    the contribution of the Gwydion Project at Carnegie Mellon
  20. //    University.
  21. // 
  22. // This software is made available "as is".  Neither the authors nor
  23. // Carnegie Mellon University make any warranty about the software,
  24. // its performance, or its conformity to any specification.
  25. // 
  26. // Bug reports, questions, comments, and suggestions should be sent by
  27. // E-mail to the Internet address "gwydion-bugs@cs.cmu.edu".
  28. //
  29. //======================================================================
  30.  
  31. /*
  32.  * This is an array implementation that depends upon vectors being
  33.  * implemented.
  34.  */
  35.  
  36. /* ------------- */
  37.  
  38. define constant no-default = list (#"no-default");
  39.  
  40. /* ------------- */
  41.  
  42. define class <multiD-array> (<array>)
  43.   slot dimensions-slot  :: <simple-object-vector>;  // Sequence of integers
  44.   slot contents-slot    :: <simple-object-vector>;
  45.   slot size-slot        :: <integer>;
  46. end class <multiD-array>;
  47.  
  48. /* ------------- */
  49.  
  50. // Array stuff
  51.  
  52.  
  53. define method make (c :: singleton (<array>), 
  54.             #key dimensions: dimensions :: <sequence> = no-default,
  55.             fill: fill = #f);
  56.  
  57.   if (dimensions == no-default)
  58.     error ("Need the dimensions or a size for an array");
  59.   elseif (size (dimensions) = 1)
  60.     make (<vector>, fill: fill, size: head (dimensions));
  61.   else
  62.     make (<multiD-array>, dimensions: dimensions, fill: fill);
  63.   end if;
  64. end method make;
  65.  
  66. /* ------------- */
  67.  
  68. define method row-major-index (array :: <array>, #rest indices)
  69.                        => index :: <integer>;
  70.   let dims = dimensions (array);
  71.   let sum = 0;
  72.  
  73.   if ( size (indices) ~= size (dims) )
  74.     error ( "Number of indices not equal to rank. Got %=, wanted %d indices",
  75.        indices, size (dims) );
  76.   else
  77.     for (index in indices,
  78.      dim   in dims)
  79.       if (index < 0 | index >= dim)
  80.     error ("Array index out of bounds: %= in %=", index, indices);
  81.       else
  82.     sum := (sum * dim) + index;
  83.       end if;
  84.     end for;
  85.  
  86.     sum;
  87.   end if;
  88. end method row-major-index;           
  89.  
  90. /* ------------- */
  91.  
  92. define method aref (array :: <array>, #rest indices)
  93.   let index = apply (row-major-index, array, indices);
  94.  
  95.   array [index];             // Call element
  96. end method aref;
  97.  
  98. /* ------------- */
  99.  
  100. define method aref-setter (value, array :: <array>, #rest indices);
  101.   let index = apply (row-major-index, array, indices);
  102.  
  103.   array [index] := value;    // Call element-setter
  104. end method aref-setter;
  105.  
  106. /* ------------- */
  107.  
  108. // rank -- the number of dimensions
  109.  
  110. define method rank (array :: <array>) => the-rank-of-array :: <integer>;
  111.   size (dimensions (array));
  112. end method rank;
  113.  
  114. /* ------------- */
  115.  
  116. // Also defined below on multiD-arrays
  117.  
  118. define method size (array :: <array>) => size :: <integer>;
  119.   reduce (\*, 1, dimensions (array));
  120. end method size;
  121.  
  122. /* ------------- */
  123.  
  124. define method dimension (array :: <array>, axis :: <integer>) 
  125.              => dim-of-that-axis :: <integer>;
  126.   (dimensions (array)) [axis];
  127. end method dimension;
  128.  
  129. /* ------------- */
  130.  
  131. define method forward-iteration-protocol (array :: <array>)
  132.   => (initial-state          :: <integer>,   limit           :: <integer>,
  133.       next-state             :: <function>,  finished-state? :: <function>,
  134.       current-key            :: <function>,  current-element :: <function>,
  135.       current-element-setter :: <function>,  copy-state      :: <function>);
  136.  
  137.   values ( 0,                 // initial state
  138.        size (array),      // limit 
  139.  
  140.           // next-state
  141.        method (array :: <array>, state :: <integer>)    
  142.          state + 1;
  143.        end method,
  144.  
  145.          // finished-state?
  146.        method (array :: <array>, state :: <integer>, limit :: <integer>)
  147.          state = limit;
  148.        end method,
  149.  
  150.          // current-key
  151.        method (array :: <array>, state :: <integer>) => key :: <integer>;
  152.          state;
  153.        end method,
  154.  
  155.          // current-element
  156.       method (array :: <array>, state :: <integer>)
  157.         array [state];
  158.       end method,
  159.  
  160.         // current-element-setter
  161.       method (value, array :: <array>, state :: <integer>)
  162.         array [state] := value;
  163.       end method,
  164.  
  165.         // copy-state
  166.       method (array :: <array>, state :: <integer>) 
  167.            => new-state :: <integer>;
  168.         state;
  169.       end method
  170.     );
  171. end method forward-iteration-protocol;
  172.  
  173. /* ------------- */
  174.  
  175. define method backward-iteration-protocol (array :: <array>)
  176.   => (final-state            :: <integer>,   limit           :: <integer>,
  177.       previous-state         :: <function>,  finished-state? :: <function>,
  178.       current-key            :: <function>,  current-element :: <function>,
  179.       current-element-setter :: <function>,  copy-state      :: <function>);
  180.  
  181.   values ( size (array) - 1,                 // final state
  182.        -1,                                // limit 
  183.  
  184.           // next-state
  185.        method (array :: <array>, state :: <integer>)    
  186.          state - 1;
  187.        end method,
  188.  
  189.          // Everything else the same as forward-iteration-protocol
  190.  
  191.          // finished-state?
  192.        method (array :: <array>, state :: <integer>, limit :: <integer>)
  193.          state = limit;
  194.        end method,
  195.  
  196.          // current-key
  197.        method (array :: <array>, state :: <integer>) => key :: <integer>;
  198.          state;
  199.        end method,
  200.  
  201.          // current-element
  202.       method (array :: <array>, state :: <integer>)
  203.         array [state];
  204.       end method,
  205.  
  206.         // current-element-setter
  207.       method (value, array :: <array>, state :: <integer>)
  208.         array [state] := value;
  209.       end method,
  210.  
  211.         // copy-state
  212.       method (array :: <array>, state :: <integer>) 
  213.            => new-state :: <integer>;
  214.         state;
  215.       end method
  216.     );
  217. end method backward-iteration-protocol;
  218.  
  219. /* ------------- */
  220.  
  221. // multiD-array code
  222.  
  223. define method initialize (array :: <multiD-array>, 
  224.               #key dimensions: dimensions :: <sequence>,
  225.               fill: fill = #f);
  226.  
  227.   if ( size (dimensions) == 1 )
  228.     // This code should never be executed unless someone calls
  229.     // make on a <multiD-array> instead of make (<array>)
  230.  
  231.     error ("Can't make a <multiD-array> with 1 dimension");
  232.   end if;
  233.  
  234.   array.dimensions-slot := as (<simple-object-vector>, dimensions);
  235.  
  236.   let total-size = reduce (\*, 1, array.dimensions-slot);
  237.   array.size-slot := total-size;
  238.  
  239.   array.contents-slot := make (<simple-object-vector>, 
  240.                    size: total-size, fill: fill);
  241. end method initialize;
  242.  
  243. /* ------------- */
  244.  
  245. define method element (array :: <multiD-array>, index :: <integer>,
  246.                #key default: default = no-default);
  247.   if (default == no-default)
  248.     array.contents-slot [index];
  249.   else
  250.     element (array.contents-slot, index, default: default);
  251.   end if;
  252. end method element;
  253.  
  254. /* ------------- */
  255.  
  256. define method element-setter (value, array :: <multiD-array>, 
  257.                   index :: <integer>);
  258.   array.contents-slot [index] := value;
  259. end method element-setter;
  260.  
  261. /* ------------- */
  262.  
  263. define method size (array :: <multiD-array>) => size :: <integer>;
  264.   array.size-slot;
  265. end method size;
  266.  
  267. /* ------------- */
  268.  
  269. define method class-for-copy (c :: singleton (<multiD-array>)) 
  270.                   => array :: <class>;
  271.   <array>;
  272. end method class-for-copy;
  273.  
  274. /* ------------- */
  275.  
  276. define method dimensions (array :: <multiD-array>) => dimensions :: <sequence>;
  277.   array.dimensions-slot;
  278. end method dimensions;
  279.  
  280.